﻿// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX - License - Identifier: Apache - 2.0.

namespace MidLevelScanOnlyExample
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Threading.Tasks;
  using Amazon.DynamoDBv2;
  using Amazon.DynamoDBv2.DocumentModel;

  // snippet-start:[dynamodb.dotnet35.MidLevelScanOnly]

  /// <summary>
  /// Shows how to use mid level Amazon DynamoDB API calls to scan a DynamoDB
  /// table for values. This example was created using the AWS SDK for .NET
  /// version 3.7 and .NET Core 5.0.
  /// </summary>
  public class MidLevelScanOnly
  {
    static async Task Main()
    {
      IAmazonDynamoDB client = new AmazonDynamoDBClient();

      Table productCatalogTable = Table.LoadTable(client, "ProductCatalog");

      await FindProductsWithNegativePrice(client, productCatalogTable);
      await FindProductsWithNegativePriceWithConfig(client, productCatalogTable);
    }

    /// <summary>
    /// Retrieves any products that have a negative price in a DynamoDB table.
    /// </summary>
    /// <param name="client">An initialized DynamoDB client object.</param>
    /// <param name="productCatalogTable">A DynamoDB table object.</param>
    public static async Task FindProductsWithNegativePrice(
      IAmazonDynamoDB client,
      Table productCatalogTable)
    {
      // Assume there is a price error. So we scan to find items priced < 0.
      ScanFilter scanFilter = new ScanFilter();
      scanFilter.AddCondition("Price", ScanOperator.LessThan, 0);

      Search search = productCatalogTable.Scan(scanFilter);

      do
      {
        var documentList = await search.GetNextSetAsync();
        Console.WriteLine("\nFindProductsWithNegativePrice: printing ............");

        foreach (var document in documentList)
        {
          PrintDocument(document);
        }
      } while (!search.IsDone);
    }

    /// <summary>
    /// Finds any items in the ProductCatalog table using a DynamoDB
    /// conguration object.
    /// </summary>
    /// <param name="client">An initialized DynamoDB client object.</param>
    /// <param name="productCatalogTable">A DynamoDB table object.</param>
    public static async Task FindProductsWithNegativePriceWithConfig(
      IAmazonDynamoDB client,
      Table productCatalogTable)
    {
      // Assume there is a price error. So we scan to find items priced < 0.
      ScanFilter scanFilter = new ScanFilter();
      scanFilter.AddCondition("Price", ScanOperator.LessThan, 0);

      ScanOperationConfig config = new ScanOperationConfig()
      {
        Filter = scanFilter,
        Select = SelectValues.SpecificAttributes,
        AttributesToGet = new List<string> { "Title", "Id" },
      };

      Search search = productCatalogTable.Scan(config);

      do
      {
        var documentList = await search.GetNextSetAsync();
        Console.WriteLine("\nFindProductsWithNegativePriceWithConfig: printing ............");

        foreach (var document in documentList)
        {
          PrintDocument(document);
        }
      } while (!search.IsDone);
    }

    /// <summary>
    /// Displays the details of the passed DynamoDB document object on the
    /// console.
    /// </summary>
    /// <param name="document">A DynamoDB document object.</param>
    public static void PrintDocument(Document document)
    {
      Console.WriteLine();
      foreach (var attribute in document.GetAttributeNames())
      {
        string stringValue = null;
        var value = document[attribute];
        if (value is Primitive)
        {
          stringValue = value.AsPrimitive().Value.ToString();
        }
        else if (value is PrimitiveList)
        {
          stringValue = string.Join(",", (from primitive
            in value.AsPrimitiveList().Entries
            select primitive.Value).ToArray());
        }

        Console.WriteLine($"{attribute} - {stringValue}");
      }
    }
  }

  // snippet-end:[dynamodb.dotnet35.MidLevelScanOnly]
}
